import { MD5 } from "crypto-js";
import { getSysDictByName, getBizDictByName } from "@/api";
import { getAppDownloadinfoCheckAppVerson } from "@/api/public/version";

import store from "@/store";
import { asyncExecFunction } from "@/king-components/js/KingonPlus";
import silenceUpdate from "@/uni_modules/rt-uni-update/js_sdk/silence-update";

// 在文件顶部添加类型定义
interface UpgradeCallbackData {
  code: number;
  msg: string;
  OldVersion: string;
  appVersionNum: string;
  appUpdateUrl: string;
  updateContent: string;
}

export function getMD5Hash(input: string) {
  const md5Hash = MD5(input);
  const md5HashUpperCase = md5Hash.toString().toUpperCase();
  return md5HashUpperCase;
}

export function newDate(date: string | number | Date) {
  const sys = uni.getSystemInfoSync();
  const platform = sys.platform;
  let d = new Date(date);
  if (platform === "ios" && typeof date === "string") {
    const [year, month, day, hour, minute, second] = date.split(/[- : \/]/).map(Number);
    d = new Date(year, month - 1, day, hour, minute, second);
  }
  return d;
}

export function getDateTxt(date: string) {
  const d = newDate(date);
  const year = d.getFullYear();
  const month = d.getMonth() + 1;
  const day = d.getDate();
  const hour = d.getHours();
  const minute = d.getMinutes();
  const second = d.getSeconds();
  return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
}

/**
 * 判断是否过期
 */
export const isOverdue = (expiration: number, time: number) => {
  if (!time || !expiration) return true;
  const expTime = new Date(time + expiration).getTime();
  const nowTime = new Date().getTime();
  return nowTime > expTime;
};

// 分割字符串成数组
export const splitStrToArray = (str: string, separator: string = ",") => {
  if (!str) return [];
  return str.split(separator).filter((v) => v !== "");
};

/** 字典 */

// 获取系统字典
export const loadSysDict = async (names: string | string[]) => {
  if (!names) return [];
  try {
    // 存储字典
    const dicts: any = {};
    const dictName = [];
    if (Array.isArray(names)) {
      dictName.push(...names);
    } else {
      dictName.push(names);
    }
    for (const v of dictName) {
      // 先判断store中是否有 并且未过期，有则直接返回
      const { expire, dictsMap } = store.getters["dicts/getDictState"];
      const find = dictsMap?.[v];
      // console.log("find ", { dictsMap, v, expire, find, isExpire: isOverdue(expire, find.update)});
      if (find?.data && !isOverdue(expire, find.update)) {
        // console.log("store中已有字典：", v);
        dicts[v] = find?.data;
      } else {
        const { data } = await getSysDictByName(v);
        dicts[v] = data;
      }
    }
    // 存store
    // console.log('loadSysDict store', store)
    store.commit("dicts/setDicts", dicts);
    return dicts;
  } catch (error) {
    console.error("加载字典失败：", error);
  }
};
// 获取业务字典
export const loadBizDict = async (names: string | string[]) => {
  if (!names) return [];
  try {
    // 存储字典
    const dicts: any = {};
    const dictName = [];
    if (Array.isArray(names)) {
      dictName.push(...names);
    } else {
      dictName.push(names);
    }
    for (const v of dictName) {
      // 先判断store中是否有 并且未过期，有则直接返回
      const { expire, dictsMap } = store.getters["dicts/getDictState"];
      const find = dictsMap?.[v];
      // console.log("find ", { dictsMap, v, expire, find, isExpire: isOverdue(expire, find.update)});
      if (find?.data && !isOverdue(expire, find.update)) {
        // console.log("store中已有字典：", v);
        dicts[v] = find?.data;
      } else {
        const { data } = await getBizDictByName({ code: v });
        dicts[v] = data;
      }
    }
    // 存store
    const store = useStore();
    store.commit("dicts/setDicts", dicts);
    return dicts;
  } catch (error) {
    console.error("加载字典失败：", error);
  }
};

/** 从字段获取中文值
 * @param {string} dictName 字典名称
 * @param {string} dictValue 字典值
 * @returns {string} 字典标签
 */

export const getFieldValue = (dictName: string, dictValue: number) => {
  // const store = useStore();
  const storeDicts = store.state.dicts.dictsMap;
  // console.log('dict--storeDicts:', storeDicts);
  const d = storeDicts?.[dictName]?.data;
  // console.log('dict--dictName:', d,  dictName,storeDicts);
  // 找不到字典，先返回字段原值，如果字段原值为空/null/undefinded 则返回默认值
  if (!d) return dictValue || "-";
  return d.find((v: any) => v.dictValue == dictValue)?.dictLabel || dictValue;
};

/** 从自定义字典获取中文值
 * @param {string} dictName 字典名称
 * @param {string} dictValue 字典值
 * @returns {string} 字典标签
 */
export const getFieldValueByThisDict = (dictName: string, dictValue: number, dicts: any) => {
  // console.log('dict--storeDicts:', storeDicts);
  const d = dicts?.[dictName];
  // console.log('dict--dictName:', d,  dictName,dicts);
  // 找不到字典，先返回字段原值，如果字段原值为空/null/undefinded 则返回默认值
  if (!d) return dictValue || "-";
  return d.find((v: any) => v.dictValue == dictValue)?.dictLabel || dictValue;
};

interface DataComDict {
  text: string;
  value: string | number | boolean;
}

/** 从datacom规范的字典获取中文值
 * @param {string} dictValue 字典名称
 * @param {array} dicts 字典
 * @returns {string} 字典标签
 */
export const getFieldValueByDatacom = (dictValue: number | string, dicts: DataComDict[]) => {
  // console.log('dict--dictName:', d,  dictName,dicts);
  // 找不到字典，先返回字段原值，如果字段原值为空/null/undefinded 则返回默认值
  if (!dicts) return dictValue || "-";
  return dicts.find((v: any) => v.value == dictValue)?.text || dictValue;
};

/**
 * 字符串转金额
 * @param {string} str
 * @param {boolean} useThousandth 是否转换千分位
 * @returns {string}
 */
export const formatMoney = (str: string | number, useThousandth: boolean = false) => {
  if (!str || str == "0") return "0.00";
  // 考虑非数字情况
  if (isNaN(parseFloat(str + ""))) return "-.--";
  let mony = parseFloat(str + "").toFixed(2);
  if (useThousandth) {
    mony = mony.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  }
  return mony;
};

/**
 * 将字典数据转成 DataCom 格式({text: xx, value: xx})
 */
export const formatDictData = (data: any[], addEmptyItem = false) => {
  if (!data || !Array.isArray(data)) return [];
  const newDict = data.map((v) => ({ text: v.dictValue, value: v.dictValue }));
  if (addEmptyItem) {
    return [{ text: "无", value: "" }, ...newDict];
  } else {
    return newDict;
  }
};

/**
 * 普通对象转 url 参数
 */
export const obj2urlParams = (obj: any) => {
  return Object.keys(obj)
    .map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`)
    .join("&");
};

/** 支付工具 */
export const identifyPaymentCode = (code: string) => {
  // 首先去除可能存在的空格
  code = code.replace(/\s/g, "");

  // 微信支付码规则：18位纯数字，以10、11、12、13、14、15开头
  if (/^(10|11|12|13|14|15)\d{16}$/.test(code)) {
    return "wechatPay";
  }

  // 支付宝支付码规则：25 - 30开头的长度为16~24位的数字
  if (/^(25|26|27n|28|29|30)\d{15,23}$/.test(code)) {
    return "alipay";
  }

  // 如果不符合上述规则，返回未知
  console.warn("支付码格式错误:", code);
  return null;
};

// 获取adnroidId
export const getAndroidId = () => {
  try {
    // 需要原生插件支持
    plus.android.importClass("android.provider.Settings");
    const context = plus.android.runtimeMainActivity().getApplicationContext();
    const androidId = plus.android.invoke(
      "android.provider.Settings$Secure",
      "getString",
      context.getContentResolver(),
      "android_id"
    );
    return androidId;
  } catch (e) {
    return "";
  }
};

// 获取设备id (uni 随机ID , 卸载会重置)
export const getDeviceId = () => {
  try {
    return uni.getSystemInfoSync().deviceId;
  } catch (e) {
    return "";
  }
};

// 获取设备序列号 （厂家指定的）
export const getDeviceSerialNumber = async (): Promise<string> => {
  try {
    const serialNumbe = await asyncExecFunction("HnXfjGetSN");
    console.log("设备序列号", serialNumbe);
    return serialNumbe + "";
  } catch (error) {
    console.error(" 获取设备序列号失败 init", error.toString());
    return "";
  }
};

/**
 * 检查版本更新
 */
export function checkUpgrade(
  callBack: (data: UpgradeCallbackData) => void,
  autoShowPop: boolean = false,
  showIsNew: boolean = false
) {
  // 判断当前是否有正在下载更新的任务
  const isupdateing = uni.getStorageSync("APP_UPDATEING");
  if (isupdateing) {
    console.log("当前有正在下载更新的任务");
    uni.showToast({
      title: "当前有正在下载更新的任务",
      icon: "none",
    });
    return;
  }

  let callList = {
    code: 0,
    msg: "", //报错信息
    OldVersion: "", //本地版本号
    appVersionNum: "", //远程版本号
    appUpdateUrl: "", //下载地址
    updateContent: "", //更新内容
  };
  // appType 应用类型（用于多端多app）
  let list = {
    appType: import.meta.env.VITE_APP_TYPE,
    appEdition: 1, // android/ios
  };
  let new_platform = plus.os.name;
  console.log("***手机操作系统***" + new_platform);
  if (new_platform == "Android") list.appEdition = 1;
  else if (new_platform == "iOS") list.appEdition = 2;
  plus.runtime.getProperty(plus.runtime.appid, function (widgetInfo) {
    callList.OldVersion = widgetInfo.version ?? "0.0.0";
    console.log("***plus - getProperty***", widgetInfo, list);
    getAppDownloadinfoCheckAppVerson(list)
      .then((res) => {
        console.log("***CheckAppVerson***", res);
        if (res.code == 200 && res.data && checkUpgradeCompareVersion(callList.OldVersion, res.data.appVersionNum)) {
          callList.code = res.code;
          callList.msg = res.msg;
          callList = Object.assign(callList, res.data);
          callBack(callList);
          console.log("appupdate-res", res, { autoShowPop });
          if (autoShowPop) {
            /** 下载文件链接的处理 (现在获取到的地址是重定向地址，直接下载会有问题) */
            if (/\?appdownUrl\=/.test(res.data.appUpdateUrl)) {
              // https://saas.zhtuoyu.cn/enclosure/enclosure/App/%E6%99%BA%E6%85%A7%E6%89%98%E8%82%B2.html?appdownUrl=https://saas.zhtuoyu.cn/enclosure/enclosure/App/%E6%99%BA%E6%85%A7%E6%89%98%E8%82%B2.apk
              let appdownUrl = res.data.appUpdateUrl.split("?appdownUrl=")[1];
              res.data.appUpdateUrl = appdownUrl;
            }
            // 处理重定向地址
            if (/\?appdownUrl\=/.test(res.data.wgtUrl)) {
              let appdownUrl = res.data.wgtUrl.split("?appdownUrl=")[1];
              res.data.wgtUrl = appdownUrl;
            }

            // 决定最后的更新包地址
            res.data.updatePackageUrl = res.data.appUpdateUrl;
            if (res.data.updateType == 1) {
              res.data.updatePackageUrl = res.data.wgtUrl;
            }

            console.log("最终的APK/WEGT下载地址", res.data.appUpdateUrl);

            /**  */
            const updateInfo = {
              // 版本更新内容 支持<br>自动换行
              describe: res.data.updateContent,
              edition_url: res.data.updatePackageUrl, //apk、wgt包下载地址或者应用市场地址  安卓应用市场 market://details?id=xxxx 苹果store itms-apps://itunes.apple.com/cn/app/xxxxxx
              edition_force: res.data.force || 0, //是否强制更新 0代表否 1代表是
              package_type: res.data.updateType, //0是整包升级（apk或者appstore或者安卓应用市场） 1是wgt升级
              edition_issue: res.data.issue || 1, //是否发行  0否 1是 为了控制上架应用市场审核时不能弹出热更新框
              edition_number: res.data.appVersionNum, //版本号 最重要的manifest里的版本号 （检查更新主要以服务器返回的edition_number版本号是否大于当前app的版本号来实现是否更新）
              edition_name: res.data.appVersionNum, // 版本名称 manifest里的版本名称
              edition_silence: res.data.silence || 0, // 是否静默更新 0代表否 1代表是
            };

            if (updateInfo.edition_silence === true) {
              //调用静默更新方法 传入下载地址
              silenceUpdate(updateInfo.edition_url);
            } else {
              uni.navigateTo({
                url: `/uni_modules/rt-uni-update/components/rt-uni-update/rt-uni-update?obj=${JSON.stringify(
                  updateInfo
                )}`,
              });
            }
          }
        } else {
          if (showIsNew && res.data) {
            uni.showModal({
              title: "提示",
              content: "已是最新版本" + callList.OldVersion,
              showCancel: false,
            });
          }
          return callBack(callList);
        }
      })
      .catch((err) => {
        console.error("***CheckAppVerson***", err);
        callList.msg = err;
        callBack(callList);
      });
  });
}
//判断版本差异
export function checkUpgradeCompareVersion(ov: string, nv: string) {
  console.log("compareVersion:当前版本=" + ov + " 更新版本=" + nv);
  if (!ov || !nv || ov == "" || nv == "") return false;
  const b = false,
    ova = ov.split(".", 4),
    nva = nv.split(".", 4);
  for (let i = 0; i < ova.length && i < nva.length; i++) {
    const so = ova[i],
      no = parseInt(so),
      sn = nva[i],
      nn = parseInt(sn);
    if (nn > no || sn.length > so.length) return true;
    else if (nn < no) return false;
  }
  if (nva.length > ova.length && 0 == nv.indexOf(ov)) return true;
}

// 获取随机字符串id (不能是数字开头)
export function getUUID() {
  return Math.random().toString(36).substring(2);
}

// 获取url参数
export const getQueryString = (name: string) => {
  try {
    const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
    const r = reg.exec(window.location.search.substring(1));
    if (r != null) {
      return decodeURIComponent(r[2]);
    }
    return null;
  } catch (error) {
    return null;
  }
};

// 将url参数转为对象
export const getQueryObject = (url: string) => {
  try {
    url = url ?? window.location.href;
    const search = url.substring(url.lastIndexOf("?") + 1);
    const obj: any = {};
    const reg = /[^?&=]+=(?:[^?&=]*)/g; // 匹配类似a=1&b=2的字符串，使用非捕获组避免回溯
    search.replace(reg, (rs, $1, $2) => {
      const name = decodeURIComponent($1);
      let val = decodeURIComponent($2);
      val = String(val);
      obj[name] = val;
      return rs;
    });
    return obj;
  } catch (error) {
    return {};
  }
};

// 生成流水号
export const generateSerialNumber = () => {
  return new Date().getTime().toString() + Math.floor(Math.random() * 1000);
};
